package com.atguigu.yygh.hosp.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.util.StringUtils;
import com.atguigu.yygh.common.exception.ServiceException;
import com.atguigu.yygh.common.result.CoReturnFormat;
import com.atguigu.yygh.common.utils.MD5;
import com.atguigu.yygh.hosp.mapper.HospitalSetMapper;
import com.atguigu.yygh.hosp.service.IHospitalSetService;
import com.atguigu.yygh.model.hosp.HospitalSet;
import com.atguigu.yygh.param.hospSet.hospByIdParam;
import com.atguigu.yygh.param.hospSet.hospDeleteParam;
import com.atguigu.yygh.param.hospSet.hospStatusParam;
import com.atguigu.yygh.param.page.HospGetAllPage;
import com.atguigu.yygh.vo.order.SignInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.BeanUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 * 医院设置表 服务实现类
 * </p>
 *
 * @author 方哥哥
 * @since 2022-03-14
 */
@Service
public class HospitalSetServiceImpl extends ServiceImpl<HospitalSetMapper, HospitalSet> implements IHospitalSetService {

    /**
     * 逻辑删除医院设置
     * @param param
     */
    @Override
    public void delectHosp(hospDeleteParam param) {
        // 判断是否为 单个删除
        if(param.getId()!=null) {
            //从数据库查找该记录是否存在,若不为空则进行删除操作
            if (this.getById(param.getId())!=null){
                this.removeById(param.getId());
            }else{
                //数据库查找不到该记录，抛出异常
                throw new ServiceException(CoReturnFormat.NO_HOSP_EXIST, "删除医院信息id["+param.getId()+"]失败,"+CoReturnFormat.getMessage(CoReturnFormat.NO_HOSP_EXIST));
            }
        }// 判断是否为 批量删除
        else if(param.getIds().size()!=0 && param.getIds()!=null) {
            List<Long> delFail=new ArrayList<>();
            List<Long> ids = param.getIds();
            for (Long id : ids) {
                if (this.getById(id)!=null){
                    this.removeById(id);
                }else{
                    delFail.add(id);
                }
            }
            if (delFail.size()!=0){
                throw new ServiceException(CoReturnFormat.NO_HOSP_EXIST, "批量删除医院信息ids"+delFail+"失败,"+CoReturnFormat.getMessage(CoReturnFormat.NO_HOSP_EXIST));
            }
        }// 如果 id 和 ids 都为 null 则抛出异常
        else {
            throw new ServiceException(CoReturnFormat.DEL_ERROR,CoReturnFormat.getMessage(CoReturnFormat.DEL_ERROR));
        }
    }

    /**
     * 分页查询
     * @param param
     * @return
     */
    @Override
    public Page<HospitalSet> getPage(HospGetAllPage param) {
        QueryWrapper<HospitalSet> queryWrapper = new QueryWrapper<>();
        if(StrUtil.isNotBlank(param.getHosname())){
            //模糊查询医院名
            queryWrapper.like("hosp_name",param.getHosname());
        }
        if(StrUtil.isNotBlank(param.getHoscode())){
            //精准查询字典类型
            queryWrapper.eq("hosp_code",param.getHoscode());
        }
        return this.page(new Page<>(param.getPageNum(),param.getPageSize()),queryWrapper);
    }

    /**
     * 新增或修改医院设置
     * @param hospitalSet
     */
    @Override
    public void saveHosp(HospitalSet hospitalSet) {
        QueryWrapper<HospitalSet> wrapper = new QueryWrapper<>();
        //获取请求体的医院code和api路径
        wrapper.eq("hosp_code", hospitalSet.getHospCode()).or().eq("api_url", hospitalSet.getApiUrl());
        //查询请求传过来的医院与已存在医院的code和路径重复的数据集合
        List<HospitalSet> HospList = this.list(wrapper);
        //重复记录为零时，菜单插入或修改操作可以直接进行
        if (HospList.size() == 0) {
            //当id不为空时，进行插入操作
            if (hospitalSet.getId() == null) {
                //设置状态 1 使用 0 不能使用
                hospitalSet.setStatus(1);
                //设置医院的签名秘钥
                Random random = new Random();
                //根据当前时间和一个随机数进行MD5的加密
                hospitalSet.setSignKey(MD5.encrypt(System.currentTimeMillis()+""+random.nextInt(1000)));
                this.save(hospitalSet);
            } else {
                // 进行修改操作
                this.updateById(hospitalSet);
            }
        } else {
            //如果重复记录为一条，并且修改id等于查询出来的记录id则表明此时修改原来的记录
            if (HospList.size() == 1 && HospList.get(0).getId().equals(hospitalSet.getId())) {
                // 进行修改操作
                this.updateById(hospitalSet);
            } else {
                HospList.removeIf(hosp -> hosp.getId()== hospitalSet.getId());
                System.out.println("+++++++++++++++++++++++++++++++++++++");
                System.out.println(HospList.get(0));
                System.out.println(hospitalSet);
                List<String> list = dealDiff(hospitalSet,HospList.get(0));
                //抛出异常 医院重复
                throw new ServiceException(CoReturnFormat.HOSP_EXIST, CoReturnFormat.getMessage(CoReturnFormat.HOSP_EXIST)+", "+list+" 重复");
            }
        }
    }

    @Override
    public void setHospStatus(hospStatusParam param) {
        if(param.getStatus()==null || param.getId()==null){
            //抛出异常 参数错误
            throw new ServiceException(CoReturnFormat.PARAM_ERROR, CoReturnFormat.getMessage(CoReturnFormat.PARAM_ERROR));
        }
        //根据id查询医院设置信息
        HospitalSet hospitalSet = this.getById(param.getId());
        //设置状态
        hospitalSet.setStatus(param.getStatus());
        //调用方法
        this.updateById(hospitalSet);
    }

    @Override
    public void sentlock(hospByIdParam param) {
        if(param.getId()==null){
            //抛出异常 参数错误
            throw new ServiceException(CoReturnFormat.PARAM_ERROR, CoReturnFormat.getMessage(CoReturnFormat.PARAM_ERROR));
        }
        HospitalSet hospitalSet = this.getById(param.getId());
        String signKey = hospitalSet.getSignKey();
        String hoscode = hospitalSet.getHospCode();
        //TODO 发送短信
    }

    /**
     * 获取签名
     * @param hoscode
     * @return
     */
    @Override
    public String getSignkey(String hoscode) {
        QueryWrapper<HospitalSet> wrapper=new QueryWrapper();
        wrapper.eq("hosp_code",hoscode);
        HospitalSet hospitalSet = baseMapper.selectOne(wrapper);
        return hospitalSet.getSignKey();
    }

    @Override
    public void checkSignKey(Map<String, Object> paramMap) {
        //获取医院系统传递过来的签名，签名已经经过MD5加密
        String sign = (String) paramMap.get("sign");
        //判断传递过来的签名是否为空
        if(StringUtils.isEmpty(sign)) {
            //抛出异常 签名错误
            throw new ServiceException(CoReturnFormat.SING_ERROR, CoReturnFormat.getMessage(CoReturnFormat.SING_ERROR));
        }
        String hoscode = (String)paramMap.get("hoscode");
        if(StringUtils.isEmpty(hoscode)) {
            //抛出异常 医院编号错误
            throw new ServiceException(CoReturnFormat.HOSP_CODE_EXIST, CoReturnFormat.getMessage(CoReturnFormat.HOSP_CODE_EXIST));
        }
        //根据医院编号，查询数据库中的签名
        String Signkey=this.getSignkey(hoscode);
        //将查找出来的签名进行MD5加密
        String SignkeyMD5 = MD5.encrypt(Signkey);
        if(!sign.equals(SignkeyMD5)){
            //抛出异常 签名错误
            throw new ServiceException(CoReturnFormat.SING_ERROR, CoReturnFormat.getMessage(CoReturnFormat.SING_ERROR));
        }
    }

    @Override
    public SignInfoVo getSignInfoVo(String hoscode) {
        QueryWrapper<HospitalSet> wrapper = new QueryWrapper<>();
        wrapper.eq("hosp_code",hoscode);
        HospitalSet hospitalSet = baseMapper.selectOne(wrapper);
        if(null == hospitalSet) {
            throw new ServiceException(CoReturnFormat.PARAM_ERROR, CoReturnFormat.getMessage(CoReturnFormat.PARAM_ERROR));
        }
        SignInfoVo signInfoVo = new SignInfoVo();
        signInfoVo.setApiUrl(hospitalSet.getApiUrl());
        signInfoVo.setSignKey(hospitalSet.getSignKey());
        return signInfoVo;
    }

    private List<String> dealDiff(HospitalSet hospNew, HospitalSet hospOld) {
        List<String> resultList = new ArrayList<>();
        HashMap<String, String> checkList = new HashMap<>();
        checkList.put("hospCode","医院编号");
        checkList.put("apiUrl","医院接口路径");
        Map<String, Object> NewMap = BeanUtils.beanToMap(hospNew);
        Map<String, Object> OldMap = BeanUtils.beanToMap(hospOld);
        for (String key : checkList.keySet()) {
            if (NewMap .get(key).equals(OldMap .get(key))) {
                resultList.add(checkList.get(key));
            }
        }
        return resultList;
    }

}
